
#include "set_systemclock.h"
#include "stm32l4xx_ll_rcc.h"
#include "stm32l4xx_ll_utils.h"
#include "stm32l4xx_ll_system.h"





/*设置.
The maximum frequency of the AHB, the 
APB1 and the APB2 domains is 80 MHz.
SYSCLK经AHB Presc后为HCLK。
*/
void set_system_48M(void)
{
	//使能HSE并等待稳定。
	LL_RCC_HSE_Enable();
	while(LL_RCC_IsActiveFlag_HSERDY());
	
	//配置PLL并等待稳定。
	LL_RCC_PLL_Disable();
	while(LL_RCC_PLL_IsReady());		//等待PLLRDY为0
	/*配置PLL时钟的系统时钟（非48MHz时钟）:
	f(VCO clock) = f(PLL clock input) × (PLLN / PLLM). VCO在[64,344]MHz.
	input为16MHz，PLLM=4，PLLN=24
	PLLCLK (system clock)= VCO frequency / PLLR.(PLLR=2,4,6,8).
	*/
	LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_4,24,LL_RCC_PLLR_DIV_2);
	LL_RCC_PLL_Enable();
	LL_RCC_PLL_EnableDomain_SYS();	//使能system main PLL.
	while(0 == LL_RCC_PLL_IsReady());
	
	
	
	//从MSI切换到PLL。
	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
	__NOP();
	__NOP();
	while(LL_RCC_SYS_CLKSOURCE_STATUS_HSE != LL_RCC_GetSysClkSource());
	
	__NOP();
	__NOP();	
}	


/*设置SYSCLK为48MHz（第2种方法）
*/
void set_systemclock_48M_2(void)
{

	LL_UTILS_PLLInitTypeDef pll_init;
	LL_UTILS_ClkInitTypeDef clk_init;
	
	pll_init.PLLM= LL_RCC_PLLM_DIV_4;
	pll_init.PLLN= 24;
	pll_init.PLLR= LL_RCC_PLLR_DIV_2;
	
	clk_init.AHBCLKDivider= LL_RCC_SYSCLK_DIV_1;
	clk_init.APB1CLKDivider= LL_RCC_APB1_DIV_1;
	clk_init.APB2CLKDivider= LL_RCC_APB2_DIV_1;
	
	
	LL_PLL_ConfigSystemClock_HSE(16000000, LL_UTILS_HSEBYPASS_OFF, &pll_init, &clk_init);
}


/*设置SYSCLK为64MHz（第2种方法）
*/
void set_systemclock_64M_2(void)
{

	LL_UTILS_PLLInitTypeDef pll_init;
	LL_UTILS_ClkInitTypeDef clk_init;
	
	pll_init.PLLM= LL_RCC_PLLM_DIV_4;
	pll_init.PLLN= 32;
	pll_init.PLLR= LL_RCC_PLLR_DIV_2;
	
	clk_init.AHBCLKDivider= LL_RCC_SYSCLK_DIV_1;
	clk_init.APB1CLKDivider= LL_RCC_APB1_DIV_1;
	clk_init.APB2CLKDivider= LL_RCC_APB2_DIV_1;
	
	
	LL_PLL_ConfigSystemClock_HSE(16000000, LL_UTILS_HSEBYPASS_OFF, &pll_init, &clk_init);
}



/*设置SYSCLK为80MHz（第2种方法），MCU支持的最高主频。
*/
void set_systemclock_80M_2(void)
{

	LL_UTILS_PLLInitTypeDef pll_init;
	LL_UTILS_ClkInitTypeDef clk_init;
	
	pll_init.PLLM= LL_RCC_PLLM_DIV_4;
	pll_init.PLLN= 40;
	pll_init.PLLR= LL_RCC_PLLR_DIV_2;
	
	clk_init.AHBCLKDivider= LL_RCC_SYSCLK_DIV_1;
	clk_init.APB1CLKDivider= LL_RCC_APB1_DIV_1;
	clk_init.APB2CLKDivider= LL_RCC_APB2_DIV_1;
	
	
	LL_PLL_ConfigSystemClock_HSE(16000000, LL_UTILS_HSEBYPASS_OFF, &pll_init, &clk_init);
}


void set_system_64M(void)
{
	//使能HSE并等待稳定。
	LL_RCC_HSE_Enable();
	while(LL_RCC_IsActiveFlag_HSERDY());
	
	//配置PLL并等待稳定。
	LL_RCC_PLL_Disable();
	while(LL_RCC_PLL_IsReady());		//等待PLLRDY为0
	/*配置PLL时钟的系统时钟（非48MHz时钟）:
	f(VCO clock) = f(PLL clock input) × (PLLN / PLLM). VCO在[64,344]MHz.
	input为16MHz，PLLM=4，PLLN=32 (PLLN在[8,86])。
	PLLCLK (system clock)= VCO frequency / PLLR.(PLLR=2,4,6,8).
	*/
	LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_4,24,LL_RCC_PLLR_DIV_2);
	LL_RCC_PLL_Enable();
	while(0 == LL_RCC_PLL_IsReady());
	
	LL_RCC_PLL_EnableDomain_SYS();	//使能system main PLL.
	
	//从MSI切换到PLL。
	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
	while(LL_RCC_SYS_CLKSOURCE_STATUS_PLL != LL_RCC_GetSysClkSource());
}

